package com.jason.fingerprint.utils;

import android.text.TextUtils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.regex.Pattern;

/**
 * @ClassName: CardNoUtils
 * @Description: 身份证验证
 * @Author: Jason.Zhang zhangyujn1989ok@gmail.com
 * @Date: 2015年12月30日17:54:33
 */
public class CardNoUtils {

//    private static final String []  provinceAndCitys = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",
//            31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",
//            45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",
//            65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"};

    private static final String[] powers = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
    private static final String[] parityBit = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
    private static CardNoUtils cardNoUtils = new CardNoUtils();
    private static HashMap<Integer, String> provinceAndCitys = new HashMap<Integer, String>();

    private static HashMap<String, String> genders = new HashMap<String, String>();

    static {
        genders = new HashMap<String, String>();
        genders.put("male","男");
        genders.put("female","女");

        provinceAndCitys = new HashMap<Integer, String>();
        provinceAndCitys.put(11, "北京");
        provinceAndCitys.put(12, "天津");
        provinceAndCitys.put(13, "河北");
        provinceAndCitys.put(14, "山西");
        provinceAndCitys.put(15, "内蒙古");
        provinceAndCitys.put(21, "辽宁");
        provinceAndCitys.put(22, "吉林");
        provinceAndCitys.put(23, "黑龙江");
        provinceAndCitys.put(31, "上海");
        provinceAndCitys.put(32, "江苏");
        provinceAndCitys.put(33, "浙江");
        provinceAndCitys.put(34, "安徽");
        provinceAndCitys.put(35, "福建");
        provinceAndCitys.put(36, "江西");
        provinceAndCitys.put(37, "山东");
        provinceAndCitys.put(41, "河南");
        provinceAndCitys.put(42, "湖北");
        provinceAndCitys.put(43, "湖南");
        provinceAndCitys.put(44, "广东");
        provinceAndCitys.put(45, "广西");
        provinceAndCitys.put(46, "海南");
        provinceAndCitys.put(50, "重庆");
        provinceAndCitys.put(51, "四川");
        provinceAndCitys.put(52, "贵州");
        provinceAndCitys.put(53, "云南");
        provinceAndCitys.put(54, "西藏");
        provinceAndCitys.put(61, "陕西");
        provinceAndCitys.put(62, "甘肃");
        provinceAndCitys.put(63, "青海");
        provinceAndCitys.put(64, "宁夏");
        provinceAndCitys.put(65, "新疆");
        provinceAndCitys.put(71, "台湾");
        provinceAndCitys.put(81, "香港");
        provinceAndCitys.put(82, "澳门");
        provinceAndCitys.put(91, "国外");
    }


//    public static CardNoUtils newInstance() {
//        return cardNoUtils;
//    }

    public static boolean checkAddressCode(String addressCode) {
        boolean check = "/^[1-9]\\d{5}$/".matches(addressCode);
        Pattern p = Pattern.compile("^[1-9]\\d{5}$");
        check = p.matcher(addressCode).matches();
        if (!check) {
            return false;
        }
        String code = provinceAndCitys.get(Integer.parseInt(addressCode.substring(0, 2)));
        if (code != null && !"".equals(code)) {
            return true;
        } else {
            return false;
        }
    }

    //校验出生日期
    public static boolean checkBirthDayCode(String birDayCode) {
        boolean check = "/^[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$/".matches(birDayCode);
        Pattern p = Pattern.compile("^[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$");
        check = p.matcher(birDayCode).matches();
        if (!check) {
            return false;
        }
        int yyyy = Integer.parseInt(birDayCode.substring(0, 4), 10);
        int mm = Integer.parseInt(birDayCode.substring(4, 6), 10);
        int dd = Integer.parseInt(birDayCode.substring(6), 10);
        Calendar calendar = new GregorianCalendar(yyyy,mm -1,dd);
        String today = new SimpleDateFormat("yyyyMMdd").format(new Date(System.currentTimeMillis()));
        if (Integer.parseInt(birDayCode) > Integer.parseInt(today)){
            return false;//生日不能大于当前日期
        }
        if (calendar.get(Calendar.YEAR) == yyyy && (calendar.get(Calendar.MONTH) + 1) == mm && calendar.get(Calendar.DAY_OF_MONTH) == dd){
            return true;
        }else {
            return false;
        }
    }

    public static String getParityBit(String idCardNo) {
        String id17 = idCardNo.substring(0, 17);
        int power = 0;
        for (int i = 0; i < 17; i++) {
            power += Integer.parseInt(String.valueOf(id17.charAt(i)), 10) * Integer.parseInt(powers[i]);
        }
        int mod = power % 11;
        return parityBit[mod];
    }

    public static boolean checkParityBit(String idCardNo) {
        String parityBit = String.valueOf(idCardNo.charAt(17));
        if (getParityBit(idCardNo).equals(parityBit)) {
            return true;
        } else {
            return false;
        }
    }

    //校验18位的身份证号码
    public static boolean check18IdCardNo(String idCardNo) {
        //18位身份证号码的基本格式校验
        boolean check = "/^[1-9]\\d{5}[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\\d{3}(\\d|x|X)$/".matches(idCardNo);
        Pattern p = Pattern.compile("^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{4}$");
        check = p.matcher(idCardNo).matches();
        if (!check) {
            return false;
        }
        //校验地址码
        String addressCode = idCardNo.substring(0, 6);
        check = checkAddressCode(addressCode);
        if (!check) {
            return false;
        }
        //校验日期码
        String birDayCode = idCardNo.substring(6, 14);
        check = checkBirthDayCode(birDayCode);
        if (!check) {
            return false;
        }
        //验证校检码
//        return checkParityBit(idCardNo);
        return checkBirthDayCode(birDayCode);
    }

    public static boolean check15IdCardNo(String idCardNo){
        //15位身份证号码的基本校验
        boolean check = "/^[1-9]\\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\\d{3}$/".matches(idCardNo);
        Pattern p = Pattern.compile("^[1-9]\\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\\d{3}$");
        check = p.matcher(idCardNo).matches();
        if(!check){
            return false;
        }
        //校验地址码
        String addressCode = idCardNo.substring(0,6);
        check = checkAddressCode(addressCode);
        if(!check){
            return false;
        }
        String birDayCode = "19" + idCardNo.substring(6,12);
        //校验日期码
        return checkBirthDayCode(birDayCode);
    }

    public static boolean checkCardNo(String cardNo){
        if (cardNo != null && !"".equals(cardNo)){
            if (cardNo.length() == 15){
                return check15IdCardNo(cardNo);
            }else if (cardNo.length() == 18){
                return check18IdCardNo(cardNo);
            }else{
                return false;
            }
        }
        return false;
    }

    //获取信息
    public static HashMap<String,String> getIdCardInfo(String idCardNo){
        HashMap<String,String> infoMap = new HashMap<String, String>();
        if (idCardNo.length() == 15){
            String aday = "19" + idCardNo.substring(6,12);
            infoMap.put("birthday",formateDateCN(aday));
            if(Integer.parseInt(String.valueOf(idCardNo.charAt(14)))% 2 == 0){
                infoMap.put("gender",genders.get("female"));
            } else{
                infoMap.put("gender",genders.get("male"));
            }
        }
        return infoMap;
    }

    public static String formateDateCN (String day){
        String yyyy =day.substring(0,4);
        String mm = day.substring(4,6);
        String dd = day.substring(6);
        return yyyy + '-' + mm + '-' + dd;
    }

    //验证护照是否正确
    public static boolean checkPassport(String passWord){
        //在JavaScript中，正则表达式只能使用"/"开头和结束，不能使用双引号
        String  expression = "/^(P\\d{7})|(G\\d{8})$/";
        Pattern pattern = Pattern.compile(expression);
        return pattern.matcher(passWord).matches();
    }

    //验证邮政编码
    public static boolean checkZipCode(String code){
        return Pattern.compile("/^[0-9]{6}$/").matcher(code).matches();
    }

    //验证昵称
    public static boolean checkNickName(String name){
        return Pattern.compile("/^[\\Α-\\￥\\w]+$/").matcher(name).matches();
    }

    //验证手机
    public static boolean checkMobile(String mobile){
        if (TextUtils.isEmpty(mobile)){
            return false;
        }
        if (mobile.length() == 11 && Pattern.compile("/^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$/").matcher(mobile).matches()){
            return true;
        }
        return false;
    }

    //验证电话号码
    public static boolean checkTelephone(String telephone){
        return Pattern.compile("/^(\\d{3,4}-?)?\\d{7,9}$/g").matcher(telephone).matches();
    }

    /**
     * 验证正则表达式
     * @param rule 正则表达式规则字符串
     * @param toValid 被验证的值
     * @returns boolean
     */
    public static boolean validateReg(String rule ,String toValid){
        return Pattern.compile(rule).matcher(toValid).matches();
    }
}
